/*
 * Inventory.java
 * Team qq 2011
 */
package com.google.code.timetrail.backend;
/**
 * This class provides an object to simulate and inventory 
 * and does things like adding and subtracting items from
 * the inventory 
 * @author Anurrag
 * @version 1.01
 * Removed magic numbers and made it so that inventories get 
 * instantiated as empty and are filled in based
 * on what Persons do
 *
 *
 */
public class Inventory {
    /*
     * TODO consider how oxen type items (engines I guess) would work, IE 
     * would they be in the ship or would they be in the inventory
     */
	
	
	/**
     * engines - instance of the engine held within the inventory
     */
    /**
     * fCapacitors - instance of the FluxCapacitors held within the inventory.
     */
    /**
     * hullParts - instance of HullPart to be held within the inventory.
     */
    /**
     * food - instance of the Item Food to be held within inventory.
     */
    /**
     * fuelCells - instance of the Item FuelCell to be held within inventory.
     */
    /**
     * money - instance of the Item money that holds the players money in the inventory.
     */
    private final Item money, fuelCells, food, hullParts, fCapacitors, engines;

	/**
	 * timeBulletBills - instance of the Item TimeBulletBill that acts as ammunition.
	 */
	/**
	 * timeSuits - instance of the Item TimeSuit that acts as clothing in the inventory.
	 */
	private final Item timeSuits, timeBulletBills;

	/**
	 * INV_CAPACITY - the maximum amount of weight a player can hold.
	 * (value is 3500)
	 */
	private static final int INV_CAPACITY = 3500;

	/**
	 * INV_MIN - the minimum amount of weight a player could hold.
	 * (value is 0)
	 */
	private static final int INV_MIN = 0;

	/**
	 * invWeight - the current weight held in the inventory.
	 */
	private int invWeight;
	
	/**
	 * Constructor for Inventory.
	 * Creates instances of all the items to be held in the inventory.
	 * Sets initial weight to zero.
	 */
	public Inventory(){
		invWeight = 0;
		
		money = new Money();
		fuelCells = new FuelCell();
		food = new Food();
		hullParts = new HullPart();
		fCapacitors = new FluxCapacitor();
		engines = new Engine();
		timeSuits = new TimeSuit();
		timeBulletBills = new TimeBulletBill();


	}

	/**
	 * adds an item to the inventory without dealing with things like "cost" and "money"
	 * things like weight and capacity will still affect it
	 * @param amount how many items to be received 
	 * @param item what kind of item to be received
	
	 * @return true if an item is added and false if it is not */
	public boolean canAddItem(int amount, Item item){
		final boolean addConfirm = item.canAddCurrentAmount(amount,true);
		final int weightCheck = item.getWeight()*amount;
		if(addConfirm && (invWeight + weightCheck) <= INV_CAPACITY 
				&& (invWeight + weightCheck) >= INV_MIN){
			invWeight += weightCheck;
			item.canAddCurrentAmount(amount);
			return true;
		}
		else{
			return false;
		}
	}
	
	/**
	 * adds an item to the inventory and has a dry run option
	 * @param amount the amount of an item that you are trying to add to the inventory
	 * @param item the item you are trying to add to the inventory
	 * @param dryRunFlag the result of the dry run of canAddItem
	
	* @return true is the item is added and false if it is not*/
	public boolean canAddItem(int amount, Item item, boolean dryRunFlag){
		final boolean addConfirm = item.canAddCurrentAmount(amount, true);
		final int weightCheck = item.getWeight()*amount;
		if(dryRunFlag){
			return addConfirm && invWeight + weightCheck <= INV_CAPACITY 
					&& invWeight + weightCheck >= INV_MIN;
		}
		else{
			return canAddItem(amount,item);
		}
	}

	/**
	 * remove an item from the inventory without dealing with money
	 * still refactors weight when removed
	 * this is basically a call to add item, but with a more intuitive name
	 * @param amount the amount of items to remove from the inventory  
	 * @param item the type of item to remove
	
	 * @return true if an item is removed and false if it is not */
	public boolean canRemoveItem(int amount, Item item){
		if(amount < 0){
			return false;
		}
		else{
			return canAddItem((amount * -1), item);
		}
	}
	
	/**
	 * actually removes the item from the inventory.
	 * @param amount the amount of the item you want to remove
	 * @param item the item you want to remove
	 * @param dryRunFlag the result of the dry run call of canRemoveItem
	
	 * @return boolean */
	public boolean canRemoveItem(int amount, Item item, boolean dryRunFlag){
		if(amount < 0){
			return false;
		}
		else{
			return canAddItem((amount * -1), item, dryRunFlag);
		}
	}

	/**
	 * returns the real weight of the inventory
	
	 * @return the inventory's current weight */
	public int getInvWeight() {
		return invWeight;
	}
	
	/**
	 * sets the inventory weight, if the weight would not work return false
	 * @param invWeight the weight to set the inventory to
	
	 */
	public void setInvWeight(int invWeight) {
			this.invWeight = invWeight;
		
	}

	/**
	 * returns the instance of Money the person has
	
	 * @return the inventory's money */
	public Item getMoney() {
		return money;
	}

	/**
	 * returns the fuel cells of the inventory.
	
	 * @return the inventory's fuel cells */
	public Item getFuelCells() {
		return fuelCells;
	}

	/**
	 * returns the inventory's food
	
	 * @return the inventory's food */
	public Item getFood() {
		return food;
	}

	/**
	 * returns the inventory's hull parts.
	
	 * @return the inventory's hull parts */
	public Item getHullParts() {
		return hullParts;
	}

	/**
	 * returns the flux capacitors of the inventory.
	
	 * @return the inventory's flux capacitors */
	public Item getfCapacitors() {
		return fCapacitors;
	}

	/**
	 * returns the engines of the inventory.
	
	 * @return the inventory's engine */
	public Item getEngines() {
		return engines;
	}

	/**
	 * returns the clothing of the inventory.
	
	 * @return the Time Suits of the inventory */
	public Item getTimeSuits(){
		return timeSuits;
	}

	/**
	 * returns the time bullet bills to the inventory.
	
	 * @return the inventory's time bullet bills */
	public Item getTimeBulletBills(){
		return timeBulletBills;
	}

	/**
	 * returns the inventory's maximum capacity
	
	 * @return the inventory's maximum capacity */
	public int getCapacity() {
		return INV_CAPACITY;
	}
	
	/**
	 * Gives the string representation of the inventory.
	 * @return the string representation of the inventory
	 */
	public String toString(){
	    
        return  "Weight: " + invWeight + "\n " +
                money.toString() + ": " + money.getCurrentAmount() + "\n " +
                fuelCells.toString() + ": " + fuelCells.getCurrentAmount() + "\n " +
                food.toString() + ": " + food.getCurrentAmount() + "\n " +
                hullParts.toString() + ": " + hullParts.getCurrentAmount() + "\n " + 
                fCapacitors.toString() + ": " + fCapacitors.getCurrentAmount() + "\n " + 
                engines.toString() + ": " + engines.getCurrentAmount() + "\n " + 
                timeSuits.toString() + ": " + timeSuits.getCurrentAmount() + "\n " + 
                timeBulletBills.toString() + ": " + timeBulletBills.getCurrentAmount();
	    
	}

}




